package rifl.meres4.commons.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * Software class. Represents the 'WorkItem' in the SoftwareDevelopmentProcess.
 * @author Mark Czotter
 * @author Miklos Szennai
 *
 */
public class Software implements Serializable {

	private static final long serialVersionUID = 4217516204009358692L;
	
	// unique id for identify the software
	private int id;
	private String name;
	private String version;
	private ArrayList<SoftwareComponent> components;
	private SystemDesignPlan systemDesignPlan;
	private boolean integrated = false;
	
	/**
	 * Default constructor.
	 */
	public Software(int id) {
		this(id, "Default Software");
	}
	
	/**
	 * Constructor
	 * @param sname Name of the software product.
	 */
	public Software(int id, String sname) {
		this.id = id;
		this.name = sname;
		this.components = new ArrayList<SoftwareComponent>();
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}

	public ArrayList<SoftwareComponent> getComponents() {
		return components;
	}

	public void setComponents(ArrayList<SoftwareComponent> components) {
		this.components = components;
	}

	public SystemDesignPlan getSystemDesignPlan() {
		return systemDesignPlan;
	}

	public void setSystemDesignPlan(SystemDesignPlan systemDesignPlan) {
		this.systemDesignPlan = systemDesignPlan;
	}
	
	/**
	 * Add a component (UI or ImplClass) to this Software object.
	 * @param swc
	 */
	public synchronized void addComponent(SoftwareComponent swc)
	{
		this.components.add(swc);
	}
	
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("ID: ");
		builder.append(getId());
		builder.append(", \nSoftwareName: ");
		builder.append(getName());
		builder.append(", \nDesignPlan: ");
		builder.append(getSystemDesignPlan() == null ? false : true);
		builder.append(", \nImplComps: ");
		builder.append(numberOfImplementationClasses());
		builder.append(", \nUIComps: ");
		builder.append(numberOfUIClasses());
		builder.append(", \nIntegrated: ");
		builder.append(isIntegrated());
		builder.append(", \nVersion: ");
		builder.append(getVersion());
		return builder.toString();
	}

	private int numberOfUIClasses() {
		int number = 0;
		for (SoftwareComponent comp : this.components) {
			if (comp instanceof UIComponent) {
				number++;
			}
		}
		return number;
	}

	private int numberOfImplementationClasses() {
		int number = 0;
		for (SoftwareComponent comp : this.components) {
			if (comp instanceof ImplementationClass) {
				number++;
			}
		}
		return number;
	}
	
	public List<UIComponent> getUIComponents() {
		List<UIComponent> comps = new ArrayList<UIComponent>();
		for (SoftwareComponent swComp : this.components) {
			if (swComp instanceof UIComponent) {
				comps.add((UIComponent) swComp);
			}
		}
		return comps;
	}
	
	public List<ImplementationClass> getImplementationComponents() {
		List<ImplementationClass> comps = new ArrayList<ImplementationClass>();
		for (SoftwareComponent swComp : this.components) {
			if (swComp instanceof ImplementationClass) {
				comps.add((ImplementationClass) swComp);
			}
		}
		return comps;
	}

	public boolean isIntegrated() {
		return integrated;
	}

	public void setIntegrated(boolean integrated) {
		this.integrated = integrated;
	}

	public void setId(int id) {
		this.id = id;
	}

	public int getId() {
		return id;
	} 
}
